#pragma once

namespace hHashMapDetail
{
	template <typename Key, typename Val, typename Hash>
	struct Node
	{
		using POwner = hHashMap<Key, Val, Hash>*;
		using POwnerPtr = std::shared_ptr<POwner>;
		using PNode = Node*;
		using PNodePtr = std::shared_ptr<PNode>;
		using Iter = Iterator<Key, Val, Hash, false>;
		using CIter = Iterator<Key, Val, Hash, true>;

		using Vec = hHashVector<PNode>;
		using VecIt = typename Vec::Iter;
		using PtrVec = hHashVector<PNodePtr>;
		using PtrVecIt = typename PtrVec::Iter;

		Key _key;
		Val* _val = NULL;

		std::pair<uint8_t, VecIt> _idx;
		POwnerPtr _ppOwner;
		PNodePtr _ppParent;
		PNodePtr _ppSelfIt;
		PNodePtr _ppSelfCld;
		Vec _vec;

		size_t _num = 0;

		Node(POwnerPtr ppOwner);
		virtual ~Node();


		template<typename... Args>
		auto emplaceCallback(size_t hash, const Key& k, Args... args)->std::pair<Iter, bool>;
		auto insertCallback(size_t hash, bool hasInsert, Iter& it)->std::pair<Iter, bool>;
		Iter findCallback(size_t hash, const Key& k);
		void clearCallback();
		template <typename Func>
		auto show(std::ostream& os, Func func) const->std::ostream&;

		template<typename... Args>
		Val* addVal(Args... args);
		Iter getIter();
		Iter getNext();
	};
}

#if 0

template <typename Key, typename Val, typename Hash, size_t FstP, size_t... RestP>
struct _hHashMapNode<Key, Val, Hash, FstP, RestP...> : public _hHashMapNodeBase<Key, Val>
{
	using _Base = _hHashMapNodeBase<Key, Val>;
	using _NextNode = _hHashMapNode<Key, Val, Hash, RestP...>;

	_hHashMapNode(uint8_t idx = 0) : _hHashMapNodeBase<Key, Val>(idx) {}

};

template<typename Key, typename Val, typename Hash, size_t P>
struct _hHashMapNode<Key, Val, Hash, P> : public _hHashMapNodeBase<Key, Val>
{
	using _Base = _hHashMapNodeBase<Key, Val>;
	_hHashMapNode(uint8_t idx = 0) : _hHashMapNodeBase<Key, Val>(idx) {}

	std::pair<typename hHashMap<Key, Val, Hash>::Iter, bool> insertCallBack(_hHashMapIterator<Key, Val, Hash>& it, size_t, std::pair<const Key, Val>* pValPr);
	_hHashMapIterator<Key, Val, Hash> findCallBack(_hHashMapIterator<Key, Val, Hash>& it, size_t, const Key& k);
};
#endif
